import React, { Component } from 'react';
import styles from './Chat.scss';
import { observable, action, computed } from 'mobx';
import { observer } from 'mobx-react';

import initView from '@/cross/components/View';
const View = initView(styles);
import initText from '@/cross/components/Text';
const Text = initText(styles);
import initImage from '@/cross/components/Image';
const Image = initImage(styles);
import initScrollView from '@/cross/components/ScrollView';
const ScrollView = initScrollView(styles);
import initImageBackground from '@/cross/components/ImageBackground';
const ImageBackground = initImageBackground(styles);

import { Keyboard, KeyboardAvoidingView, Platform } from 'react-native';
import AudioRecorder from '../components/AudioRecorder';

import { Page, HeaderBar, Button, Modal, AutoList, SafeView } from '@/cross/components';
import MessageInput from '../components/MessageInput';
import MessageItem from '../components/MessageItem';
import EmotionView, { IEmotionItem } from '../components/emotion/EmotionView';

import { CrossPageProps } from '@/cross/pages/PropType';
import { Client } from '@/config';
import { px } from '@/cross/utils';
import {
  $service,
  $confirm,
  $message,
  $chooseImage,
  $chooseVideo,
  $actionSheet,
  $prewView,
  $src,
} from '@/cross/utils';
import { IMessage, ISession } from '../../types';
import { IScene } from '../../types/base';

import im, { IM } from '../store/im';
import msgAction from '../store/msg';
import uuid from '../../utils/uuid';
import util from '../../utils/im';
import { FlatList } from 'react-native';
import StatusBar from '@/cross/components/Bar/StatusBar';
import { Icon } from '@/cross/components/Icon';

export interface ChatPageProps extends CrossPageProps {
  params: {
    session: {
      to: string;
      name: string;
      avatar: string;
      scene: IScene;
    };
  };
}

@observer
class PageView extends Component<ChatPageProps> {
  componentDidMount() {}

  componentWillUnmount() {
    im.resetCurrSession();
  }

  messageInputRef: MessageInput | null = null;

  @observable msgText = '';
  @action handleInputChange = (text: string) => {
    this.msgText = text;
  };
  @action handleInputFocus = () => {
    this.showBoard = null;
  };
  @action openEmoji = () => {
    Keyboard.dismiss();
    if (this.showBoard === 'emoji') return (this.showBoard = null);
    this.showBoard = 'emoji';
  };
  onSelectEmotion = (item: IEmotionItem) => {
    const value = '[' + item.title + ']';
    let msgText = this.msgText;
    if (this.selection) {
      const { selectionStart, selectionEnd } = this.selection;
      this.msgText =
        msgText.substring(0, selectionStart) +
        value +
        msgText.substring(selectionEnd, msgText.length);
    } else {
    }
    // setInputValue(oldValue => {
    //   return oldValue.substring(0, inputSelectionStart) + value + oldValue.substring(inputSelectionEnd, oldValue.length);
    // })
    // setTimeout(() => {
    //   setInputSelectionStart(inputSelectionStart + value.length);
    //   setInputSelectionEnd(inputSelectionEnd + value.length);
    // }, 100);
  };
  selection: { selectionStart: number; selectionEnd: number } = {
    selectionStart: 0,
    selectionEnd: 0,
  };
  onSelectionChange = (value: { selectionStart: number; selectionEnd: number }) => {
    this.selection = value;
  };
  @action add = () => {
    Keyboard.dismiss();
    if (this.showBoard === 'extra') return (this.showBoard = null);
    this.showBoard = 'extra';
  };
  clearTextInput = () => {
    this.msgText = '';
    this.messageInputRef?.clearTextInput();
  };
  handleSend = () => {
    const { session } = this.props.params;
    let msgText = this.msgText;
    if (msgText == '\n' || msgText == '') return (this.msgText = '');
    this.clearTextInput();
    // start send
    msgAction.sendTextMsg({
      text: msgText,
      scene: 'p2p',
      to: session.to,
    });
  };
  @observable keyBoardHeight = 0;
  @action
  handleKeyboardChange = (type: string, event: any) => {
    console.log('handleKeyboardChange', type);
    if (type === 'show') {
      if (Platform.OS === 'ios') this.keyBoardHeight = event.endCoordinates.height;
      // 隐藏更多或表情
      this.showBoard = null;
      // setTimeout(() => {
      //   this.scrollToTop()
      // }, 100);
    } else {
      this.keyBoardHeight = 0;
    }
  };

  /**
   * 当前扩展框类型
   * @enum emoji 表情
   * @enum extra 更多
   */
  @observable showBoard: 'emoji' | 'extra' | null = null;
  /** 当前输出消息类型 */
  @observable msgType: 'text' | 'voice' = 'text';
  @action changeMsgType = () => {
    this.msgType = this.msgType === 'text' ? 'voice' : 'text';
    this.showBoard = null;
    Keyboard.dismiss();
  };

  autoListRef: FlatList<IMessage> | null = null;

  @action
  onScrollBeginDrag = () => {
    this.showBoard = null;
  };

  loading = false;
  nodata = false;
  loadPrevMsg = () => {
    if (this.loading || this.nodata || im.currentSessionMsgs.length === 0) return;
    this.loading = true;
    try {
      let end = Date.now();
      if (im.currentSessionMsgs.length > 1) {
        end = im.currentSessionMsgs[im.currentSessionMsgs.length - 1].time || 0;
      }
      msgAction.getLocalMsgs(im.currentSessionId, {
        reset: false,
        end,
        done: ({ haveNext }) => {
          if (!haveNext) this.nodata = true;
          this.loading = false;
        },
      });
    } catch (e) {
      this.nodata = true;
      this.loading = false;
    }
  };

  onClickMsg = (msg: IMessage, index: number) => {
    if (msg.type === 'image') {
      $prewView(
        $src(msg.file.url),
        im.currentSessionMsgs
          .filter((item) => item.type === 'image')
          .reverse()
          .map((item) => (item.type === 'image' ? $src(item.file.url) : '')),
      );
    }
  };

  onLongClickMsg = (msg: IMessage, index: number) => {
    $actionSheet(['删除', '取消'])
      .then((i) => {
        if (i === 0) {
          msgAction.deleteMsg(msg, index);
        }
      })
      .catch((e) => {});
  };

  renderItem = ({ item, index }: { item: IMessage; index: number }) => {
    return (
      <View key={item.key || index}>
        {item.type === 'timeTag' ? (
          <View className="M-center-all M-p-v-b-10">
            <Text className="M-f-s-12 M-f-c-999">{item.text}</Text>
          </View>
        ) : (
          <MessageItem
            key={item.key}
            message={item}
            onClick={this.onClickMsg.bind(this, item, index)}
            onLongClick={this.onLongClickMsg.bind(this, item, index)}
          />
        )}
      </View>
    );
  };

  /** 发送语音消息 */
  sendVoiceMsg = (filePath: string, duration: number) => {
    const { session } = this.props.params;
    console.log('[filePath] ', filePath);
    const fileOptions = {
      scene: session.scene,
      to: session.to,
      filePath,
      size: 1, // stat.size,
      md5: uuid(),
      dur: parseInt(String(duration)),
      callback: () => {
        console.log('====================================');
        console.log('[sendVoiceMsg]');
        console.log('====================================');
        // this.scrollToEnd();
      },
    };
    msgAction.sendAudioMsg(fileOptions);
  };

  handleClickExtra(extraType: 'location' | 'camera' | 'photo' | 'video') {
    const { session } = this.props.params;
    if (extraType === 'location') {
      // this.props.navigation.navigate('locale', {
      //   onSelect: (locale) => {
      //     console.log('[onSelectLocale] ', locale)
      //     msgAction.sendGeoMsg({
      //       scene: 'p2p',
      //       to: this.session.yunxinAccid,
      //       geo: {
      //         title: locale.title,
      //         lat: locale.location.lat,
      //         lng: locale.location.lng
      //       }
      //     })
      //   }
      // })
      setTimeout(() => {
        this.showBoard = null;
      }, 500);
      return;
    }
    if (extraType === 'video') {
      $chooseVideo({
        onProgress: () => {},
      }).then(({ tempFiles }) => {
        console.log('[chooseVideo] ', tempFiles);
        msgAction.sendImageMsg({
          type: 'video',
          scene: session.scene,
          to: session.to,
          filePath: tempFiles[0].path,
          width: tempFiles[0].width || 0,
          height: tempFiles[0].height || 0,
          size: tempFiles[0].size,
          duration: tempFiles[0].duration,
          md5: uuid(),
          // pendingUrl: `data:${response.type};base64,${response.data}`,
          callback: () => {
            this.showBoard = null;
          },
        });
      });
    }
    if (extraType === 'photo' || extraType === 'camera') {
      $chooseImage({
        count: 1,
        sourceType: extraType === 'photo' ? 'album' : 'camera',
      })
        .then(({ tempFiles }) => {
          console.log('====================================');
          console.log('[$chooseImage] ', tempFiles);
          console.log('====================================');
          msgAction.sendImageMsg({
            type: 'image',
            scene: session.scene,
            to: session.to,
            filePath: tempFiles[0].path,
            width: tempFiles[0].width || 0,
            height: tempFiles[0].height || 0,
            size: tempFiles[0].size,
            md5: uuid(),
            // pendingUrl: `data:${response.type};base64,${response.data}`,
            callback: () => {
              this.showBoard = null;
            },
          });
        })
        .catch(() => {});
    }
  }

  openSessionInfo = () => {
    this.props.navigation?.navigate('SessionInfo', {
      params: {
        session: im.currentSession,
      },
    });
  };

  render() {
    const {
      session: { name },
    } = this.props.params;
    let listData = im.currentSessionMsgs;
    return (
      <Page statusBarMode="dark" className="M-b-c-w mt-chat">
        <HeaderBar
          title={name || '聊天'}
          titleAlign="left"
          mode="light"
          leftContent={null}
          showBack
          rightContent={
            <View onClick={this.openSessionInfo} className="M-p-h-b-10 M-p-v-b-5 M-vertical-middle">
              <Icon name="mtcaozuo" theme="light" size={40} />
            </View>
          }
        />
        <KeyboardAvoidingView
          style={{ flex: 1 }}
          behavior={Platform.OS === 'ios' ? 'padding' : undefined}
        >
          <FlatList
            ref={(node) => (this.autoListRef = node)}
            inverted
            style={{ backgroundColor: '#f5f5f5', flex: 1 }}
            data={listData.slice()}
            ListHeaderComponent={<View className="M-p-t-10" />}
            ListFooterComponent={<View className="M-p-t-10" />}
            keyExtractor={(item, index) => item.key as string}
            onEndReached={this.loadPrevMsg}
            onScroll={this.onScrollBeginDrag}
            renderItem={this.renderItem}
          />
          {/* Footer */}
          <View className="mt-chat__footer M-bd-t">
            <View className="mt-chat__footer__action M-flexbox-horizontal M-vertical-bottom">
              <View
                onClick={this.changeMsgType}
                className="mt-chat__footer__action__item M-vertical-middle M-p-l-10 M-p-r-5"
              >
                <View className="mt-chat__footer__action__item__icon">
                  <Image
                    className="mt-chat__footer__action__item__icon"
                    src={
                      this.msgType === 'text'
                        ? require('../images/voice.png')
                        : require('../images/keyboard.png')
                    }
                  ></Image>
                </View>
              </View>
              {this.msgType === 'voice' ? (
                <View className="mt-chat__footer__input__body M-vertical-middle M-flex-item M-p-l-5 M-p-r-10">
                  <AudioRecorder sendAudio={this.sendVoiceMsg} />
                </View>
              ) : (
                <View className="mt-chat__footer__input__body M-vertical-middle M-flex-item">
                  <MessageInput
                    ref={(node) => (this.messageInputRef = node)}
                    display={this.msgType === 'text'}
                    value={this.msgText}
                    onChange={this.handleInputChange}
                    onFocus={this.handleInputFocus}
                    onSelectionChange={this.onSelectionChange}
                  />
                </View>
              )}
              {this.msgType !== 'voice' && (
                <React.Fragment>
                  <View
                    onClick={this.openEmoji}
                    className="mt-chat__footer__action__item M-vertical-middle M-p-h-b-5"
                  >
                    <Image
                      className="mt-chat__footer__action__item__icon"
                      src={require('../images/biaoqing.png')}
                      style={{ width: px(50), height: px(50) }}
                    ></Image>
                  </View>
                  <View className="mt-chat__footer__action__item M-vertical-middle M-p-l-5 M-p-r-10">
                    {this.msgText === '' ? (
                      <View className="" onClick={this.add}>
                        <Image
                          src={require('../images/add.png')}
                          style={{ width: px(68), height: px(68) }}
                        ></Image>
                      </View>
                    ) : (
                      <View
                        onClick={this.handleSend}
                        className="mt-chat__footer__action__send M-center-all"
                      >
                        <Image
                          src={require('../images/send.png')}
                          style={{ width: px(30), height: px(30) }}
                        ></Image>
                      </View>
                    )}
                  </View>
                </React.Fragment>
              )}
            </View>
            {/* emoji */}
            {/* { this.lazyLoadShow && <View style={{ overflow: 'hidden', height: this.showBoard === 'emoji' ? 'auto' : 0 }}>
              <ChatEmoji onSelectEmoji={ this.onSelectEmoji } />
            </View>} */}
            <View
              className={`mt-chat__footer__emotion ${
                this.showBoard === 'emoji' ? '' : 'M-display-none'
              }`}
            >
              <EmotionView onSelect={this.onSelectEmotion} />
            </View>
            {/* extra */}
            {this.showBoard === 'extra' && (
              <View className="mt-chat__footer__extra">
                <View className="mt-chat__footer__extra__row M-flexbox-horizontal M-flex-row-wrap M-p-t-10">
                  <ChatItem
                    text="相册"
                    icon={require('../images/photo.png')}
                    onClick={this.handleClickExtra.bind(this, 'photo')}
                  />
                  <ChatItem
                    text="拍照"
                    icon={require('../images/camera.png')}
                    onClick={this.handleClickExtra.bind(this, 'camera')}
                  />
                  <ChatItem
                    text="短视频"
                    icon={require('../images/video.png')}
                    onClick={this.handleClickExtra.bind(this, 'video')}
                  />
                  {/* <ChatItem text="位置" icon={require('../images/location.png')} onClick={ this.handleClickExtra.bind(this, 'location') } /> */}
                  {/* <ChatItem key={2} itemType="location" onPress={this.sendGeoMsg} />
                  <ChatItem key={3} itemType="file" onPress={this.sendFileMsg} /> */}
                </View>
              </View>
            )}
            {/* 占位填充 */}
            {
              // this.keyBoardHeight > 0 ? <View style={{ height: this.keyBoardHeight }}></View> : <SafeAreaView forceInset={{ top: "never", bottom: 'always' }} />
            }
            {/* onKeyboardChange={this.handleKeyboardChange} */}
          </View>
        </KeyboardAvoidingView>
        <View className="M-b-c-w">
          <SafeView forceInset={{ top: 'never', bottom: 'always' }} />
        </View>
      </Page>
    );
  }
}

export default PageView;

export const ChatItem = ({
  icon,
  text,
  onClick,
}: {
  icon: string;
  text: string;
  onClick: () => void;
}) => {
  return (
    <View className="mt-chat__footer__extra__button" onClick={onClick}>
      <View className="mt-chat__footer__extra__button__item M-center-all">
        <Image src={icon} className="mt-chat__footer__extra__button__icon" />
      </View>
      <View className="M-center-all M-p-t-8 M-p-b-10">
        <Text className="M-f-s-12 M-f-c-666">{text}</Text>
      </View>
    </View>
  );
};
